<template>
  <div class="water-polo">
    <div class="water-polo-chart" ref="chartEl" :style="chartStyle"></div>
    <p class="water-polo-label">{{ label }}</p>
  </div>
</template>

<script>
import { debounce } from '@/utils/index';

function Pie(color) {
  let dataArr = [];
  for (var i = 0; i < 150; i++) {
    if (i % 2 === 0) {
      dataArr.push({
        name: (i + 1).toString(),
        value: 50,
        itemStyle: {
          normal: {
            color,
            borderWidth: 0,
            borderColor: 'rgba(0,0,0,0)',
          },
        },
      });
    } else {
      dataArr.push({
        name: (i + 1).toString(),
        value: 100,
        itemStyle: {
          normal: {
            color: 'rgba(0,0,0,0)',
            borderWidth: 0,
            borderColor: 'rgba(0,0,0,0)',
          },
        },
      });
    }
  }
  return dataArr;
}

export default {
  props: {
    percentage: {
      type: Number,
      default: 0,
      validator: (value) => value >= 0 && value <= 100,
    },
    label: {
      type: String,
      default: '',
    },
    size: {
      type: [String, Number],
      default: '6.2vw',
    },
    color1: {
      type: String,
      default: '#429BF7',
    },
    color2: {
      type: String,
      default: '#6CDEFC',
    },
  },
  data() {
    return {
      chartObj: null,
    };
  },
  computed: {
    chartStyle() {
      const size = typeof this.size === 'number' ? `${this.size}px` : this.size;

      return {
        width: size,
        height: size,
      };
    },
  },
  watch: {
    percentage(newVal, oldVal) {
      if (newVal === oldVal) return;

      this.changeChart();
    },
  },
  methods: {
    initChart() {
      this.chartObj = this.$echarts.init(this.$refs.chartEl);
      
      const resizeHandle = debounce(() => {
        this.chartObj && this.chartObj.resize()
      }, 300)

      window.addEventListener('resize', resizeHandle)

      this.$once('hook:beforeDestroy', () => {
        window.removeEventListener('resize', resizeHandle)

        resizeHandle = null

        if (this.chartObj) {
          this.chartObj.dispose();
          this.chartObj = null;
        }
      });
    },
    changeChart() {
      if (!this.chartObj) this.initChart();

      const percentage = Math.min(100, this.percentage);
      const { color1, color2 } = this;

      const option = {
        backgroundColor: 'rgba(255,255,255,0)',
        series: [
          {
            type: 'liquidFill',
            radius: '70%', // 控制中间圆球的尺寸（此处可以理解为距离外圈圆的距离控制）
            center: ['50%', '50%'],
            data: [
              {
                value: percentage / 100,
                itemStyle: {
                  opacity: 0.3,
                },
              },
              {
                value: percentage / 100,
                itemStyle: {
                  opacity: 0.6,
                },
              },
              {
                value: percentage / 100,
                direction: 'left', //波浪方向
                itemStyle: {
                  opacity: 0.9,
                },
              },
            ], // data个数代表波浪数
            backgroundStyle: {
              color: new this.$echarts.graphic.RadialGradient(0.5, 0.5, 0.9, [
                { offset: 0, color: 'rgba(255, 255, 255, 0)' },
                { offset: .8, color: 'rgba(255, 255, 255, 0.2)' },
                { offset: 1, color: 'rgba(255, 255, 255, 0.6)' },
              ]), // 球体本景色
            },
            amplitude: '7%', //波浪的振幅
            // 每个波浪不同颜色，颜色数组长度为对应的波浪个数
            color: [
              {
                type: 'linear',
                x: 0,
                y: 0,
                x2: 0,
                y2: 1,
                colorStops: [
                  {
                    offset: 1,
                    color: color2,
                  },
                  {
                    offset: 0,
                    color: color1,
                  },
                ],
                globalCoord: false,
              },
            ],
            label: {
              normal: {
                formatter: `${percentage}{d|%}`,
                rich: {
                  d: {
                    fontSize: 18,
                  },
                },
                textStyle: {
                  fontSize: 18,
                  color: '#fff',
                },
              },
            },
            outline: {
              show: false,
            },
          },
          {
            type: 'pie',
            z: 1,
            center: ['50%', '50%'],
            radius: ['72%', '73.5%'], // 控制外圈圆的粗细
            hoverAnimation: false,
            data: [
              {
                name: '',
                value: 500,
                labelLine: {
                  show: false,
                },
                itemStyle: {
                  color: color1,
                },
                emphasis: {
                  labelLine: {
                    show: false,
                  },
                  itemStyle: {
                    color: color1,
                  },
                },
              },
            ],
          },
          {
            //外发光
            type: 'pie',
            z: 1,
            zlevel: -1,
            radius: ['70%', '90.5%'],
            center: ['50%', '50%'],
            hoverAnimation: false,
            clockWise: false,
            itemStyle: {
              normal: {
                borderWidth: 20,
                color: 'rgba(224,242,255,.1)',
              },
            },
            label: {
              show: false,
            },
            data: [100],
          },
          {
            //底层外发光
            type: 'pie',
            z: 1,
            zlevel: -2,
            radius: ['70%', '100%'],
            center: ['50%', '50%'],
            hoverAnimation: false,
            clockWise: false,
            itemStyle: {
              normal: {
                borderWidth: 20,
                color: 'rgba(224,242,255,.05)',
              },
            },
            label: {
              show: false,
            },
            data: [100],
          },
          {
            type: 'pie',
            zlevel: 0,
            silent: true,
            radius: ['78%', '80%'],
            z: 1,
            label: {
              normal: {
                show: false,
              },
            },
            labelLine: {
              normal: {
                show: false,
              },
            },
            data: Pie(color1),
          },
        ],
      };

      this.chartObj.setOption(option);
    },
  },
  mounted() {
    this.changeChart();
  },
};
</script>

<style scoped>
.water-polo {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}
.water-polo-chart {
  position: relative;
}
.water-polo-label {
  margin-top: 6px;
  text-align: center;
  font-size: 14px;
  color: #fff;
}
</style>
